package com.test.rpc.zookeeper;

import com.test.rpc.common.utils.CollectionUtil;
import com.test.rpc.register.ServiceDiscovery;
import io.netty.util.internal.ThreadLocalRandom;
import org.I0Itec.zkclient.ZkClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.RandomAccessFile;
import java.util.List;

public class ZookeeperServiceDiscovery implements ServiceDiscovery {
    private static final Logger LOGGER = LoggerFactory.getLogger(ZookeeperServiceDiscovery.class);
    private String zkAddress;

    public ZookeeperServiceDiscovery(String zkAddress) {
        this.zkAddress = zkAddress;
    }

    public String discover(String serviceName) {
        ZkClient zkClient = new ZkClient(zkAddress, Constants.ZK_SESSION_TIMEOUT, Constants.ZK_CONNECTION_TIMEOUT);
        LOGGER.debug("connect zookeeper");
        try {
            String servicePath = Constants.ZK_REGISTER_PATH + "/" + serviceName;
            if (!zkClient.exists(servicePath)) {
                throw new RuntimeException(String.format("can not find any service on servicepath: %s", servicePath));
            }
            List<String> children = zkClient.getChildren(servicePath);
            if (CollectionUtil.isEmpty(children)) {
                throw new RuntimeException(String.format("can not find any service on servicepath: %s", servicePath));
            }
            String address;
            int size = children.size();
            if (size == 1) {
                address = children.get(0);
                LOGGER.debug("only address node : " + address);
            } else {
                address = children.get(ThreadLocalRandom.current().nextInt(size));
                LOGGER.debug("address node : " + address);
            }
            String addressPath = servicePath + "/" + address;
            return zkClient.readData(addressPath);
        }finally {
            zkClient.close();
        }
    }
}
